﻿#include "ssLeNetwork.h"
#include "log/ssLogThread.h"

namespace StarSeeker
{

ssLeNetwork::ssLeNetwork()
{
	m_parsePackageMode = 1;
}

ssLeNetwork::~ssLeNetwork()
{
}

bool ssLeNetwork::StartNetWork(const char* ip, const u16 port, bool isClient)
{
	if (m_netThread.StartNetWork(ip, port, isClient, this))
	{
		m_netThread.SetParsePackageMode(m_parsePackageMode);
		SS_LOG->PrintEx("start network %s:%d", ip, port);
		return StartThread();
	}
	return false;
}

void ssLeNetwork::StopNetWork()
{
	m_netThread.StopNetWork();
	ExitThread();
}

void ssLeNetwork::HandleMessage(ssMsg_s &m)
{
	switch (m.msgID)
	{
	case SS_MSG_NEW_CONNECT:
		{
			ssLeSession* s = (ssLeSession*)m.param[1];
			if (s)
			{
				std::map<u32, ssLeSession*>::iterator itr = m_sessionTable.find(s->m_sessionID);
				if (itr != m_sessionTable.end())
				{
					if (m_netThread.IsClient())
					{
						//!!需要对象池
						delete itr->second;
						m_sessionTable.erase(itr);
						m_sessionTable.insert(std::pair<u32, ssLeSession*>(s->m_sessionID, s));
					}
					else
					{
						delete s;
					}
				}
				else
				{
					m_sessionTable.insert(std::pair<u32, ssLeSession*>(s->m_sessionID, s));
				}
				OnNewSession(s->m_sessionID);
			}
		}
		break;
	case SS_MSG_DISCONNECT:
		{
			std::map<u32, ssLeSession*>::iterator itr = m_sessionTable.find(m.param[0]);
			if (itr!=m_sessionTable.end())
			{
				//!!需要对象池
				delete itr->second;
				m_sessionTable.erase(itr);
				OnSessionClose(m.param[0], m.subID);
			}
		}
		break;
	case SS_MSG_RECRIVE:
		OnSessionMessage(m.param[0], 0, m.subID, (char*)m.param[1], (ssNetMsgHead*)m.param[1]);
		break;
	case SS_MSG_SEND:
		{
			char* buf = (char*)m.param[1];
			if (buf)
			{
				ssLeSession* s = FindSession(m.param[0]);
				if (s)
				{
					s->SendData(buf, m.subID);
				}
				else
				{
					SS_LOG->PrintEx("找不到socket");
				}
				//!!需要对象池
				delete[] buf;
			}

			//ssLeSession* s = FindSession(m.param[0]);
			//if (s)
			//{
				// ssNetMsgHead head(0,0);
				// s->SendData(&head, sizeof(head));
			//}
			//else
			//{
				// std::cout << "找不到socket" << std::endl;
			//}
		}
		break;
	case SS_MSG_BROADCAST:
		{
			char* buf = (char*)m.param[1];
			if (buf)
			{
				std::map<u32, ssLeSession*>::iterator itr;
				for (itr = m_sessionTable.begin(); itr != m_sessionTable.end(); ++itr)
				{
					itr->second->SendData(buf, m.subID);
				}
				//!!需要对象池
				delete[] buf;
			}
		}
		break;
	case SS_MSG_CLOSE:
		{
			std::map<u32, ssLeSession*>::iterator itr = m_sessionTable.find(m.param[0]);
			if (itr != m_sessionTable.end())
			{
				//!!需要对象池
				delete itr->second;
				m_sessionTable.erase(itr);
				OnSessionClose(m.param[0], m.subID);
			}
		}
		break;
	case SS_MSG_THREAD:
		{
			OnThreadMessage(m.subID, m.param[0], m.param[1]);
		}
		break;
	}
}

ssLeSession* ssLeNetwork::FindSession(u32 id)
{
	std::map<u32, ssLeSession*>::iterator itr = m_sessionTable.find(id);
	if (itr!=m_sessionTable.end())
	{
		return itr->second;
	}
	return 0;
}

void ssLeNetwork::OnSessionMessage(u32 sessionID, u32 ip, u32 msgID, char* data, ssNetMsgHead* head)
{
	delete[] data;
}

void ssLeNetwork::OnSessionClose(u32 sessionID, u32 reason)
{

}

void ssLeNetwork::OnNewSession(u32 sessionID)
{

}

void ssLeNetwork::OnThreadMessage(u32 msgID, ulint param1, ulint param2)
{

}

void ssLeNetwork::Reconnect()
{
	m_netThread.Reconnect();
}

StarSeeker::u32 ssLeNetwork::GetUniqueSession()
{
	if (m_netThread.IsClient() && !m_sessionTable.empty())
	{
		return m_sessionTable.begin()->first;
	}
	return 0;
}

bool ssLeNetwork::IsConnect()
{
	if (!m_netThread.IsClient())
	{
		return true;
	}
	return !m_sessionTable.empty();
}

void ssLeNetwork::SetRWSize(u32 len)
{
	m_netThread.SetRWSize(len);
}

void ssLeNetwork::SetParsePackageMode(u8 mode)
{
	m_parsePackageMode = mode < 3 ? mode : 0;
}

StarSeeker::u32 ssLeNetwork::GetSessionCount()
{
	return m_sessionTable.size();
}

StarSeeker::u8 ssLeNetwork::GetParsePackageMode()
{
	return m_parsePackageMode;
}

void ssLeNetwork::DoSendData(u32 sessionId, const char * buf, u32 len)
{
	this->PostMsg(SS_MSG_SEND, len, sessionId, (ulint)buf, 0);
}

void ssLeNetwork::DoBroadcastData(const char * buf, u32 len)
{
	this->PostMsg(SS_MSG_BROADCAST, len, 0, (ulint)buf, 0);
}

void ssLeNetwork::DoCloseSocket(u32 sessionId)
{
	this->PostMsg(SS_MSG_CLOSE, SS_MANUAL_CLOSE, sessionId, 0, 0);
}

}
